home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 31 / Amiga Format CD31 (1998-09-02)(Future Publishing)(GB)(Track 1 of 2)[!][issue 1998-10].iso / -seriously_amiga- / hardware / transadf / source / infl_disk.c < prev    next >
C/C++ Source or Header  |  1998-07-20  |  9KB  |  301 lines

  1. /* infl_disk.c = Inflate a compressed file onto a disk
  2. ** Copyright (C) 1997,1998 Karl J. Ots
  3. ** 
  4. ** This program is free software; you can redistribute it and/or modify
  5. ** it under the terms of the GNU General Public License as published by
  6. ** the Free Software Foundation; either version 2 of the License, or
  7. ** (at your option) any later version.
  8. ** 
  9. ** This program is distributed in the hope that it will be useful,
  10. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. ** GNU General Public License for more details.
  13. ** 
  14. ** You should have received a copy of the GNU General Public License
  15. ** along with this program; if not, write to the Free Software
  16. ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  17. */
  18.  
  19. #include <exec/types.h>
  20. #include <exec/memory.h>
  21. #include <devices/trackdisk.h>
  22. #include <dos/dos.h>
  23. #include <clib/exec_protos.h>
  24. #include <clib/dos_protos.h>
  25.  
  26. #include <string.h>
  27.  
  28. #include "zlib.h"
  29.  
  30. #include "infl_disk.h"
  31. #include "main.h"
  32. #include "mem_chunks.h"
  33. #include "td.h"
  34. #include "util.h"
  35. #include "errors.h"
  36.  
  37.  
  38. #define ID_FBSIZE   (32*1024)                   /* Bytes in id_FileBuf   */
  39. #define ID_TBTRACKS 1                           /* Tracks in id_TrackBuf */
  40. #define ID_TBSIZE   (ID_TBTRACKS * TRACK_SIZE)  /* Bytes in id_TrackBuf  */
  41.  
  42. UBYTE *id_FileBuf;     /* Our input buffer - reads from file.     */
  43. UBYTE *id_TrackBuf;    /* Our output buffer - writes to disk.     */
  44. UBYTE *id_VTrackBuf;   /* Buffer for verifiying data if required. */
  45.  
  46. /*
  47. ** Inflate a file into a disk.
  48. ** Expects all fields of adfPkt to be set.
  49. */
  50. void inflDisk (struct ADF_Packet *adfPkt, STRPTR origName, ULONG fileType)
  51. {
  52.   static z_stream infl_stream;
  53.   ULONG nextTrack, CRC, USize, origCRC, origUSize;
  54.   LONG DOSError;
  55.   BYTE TDError;
  56.   int zerr, winbits;
  57.   
  58.   
  59.   /* Output info header */
  60.   FPrintf (StdOut, "Inflating from %s to TrackDisk Unit %ld (DF%ld:).\n",
  61.                    adfPkt->ADFileName,
  62.                    adfPkt->diskUnit,
  63.                    adfPkt->diskUnit);
  64.   
  65.   FPrintf (StdOut, "Starting at track %ld, Ending at track %ld.\n",
  66.                    (adfPkt->startTrack>>1),
  67.                    (adfPkt->endTrack>>1));
  68.   
  69.   FPuts (StdOut, "Input is a ");
  70.   switch (fileType) {
  71.   case FT_ZLIB:  FPuts (StdOut, "ZLib");  break;
  72.   case FT_GZIP:  FPuts (StdOut, "GZip");  break;
  73.   case FT_PKZIP: FPuts (StdOut, "PKZip"); break;
  74.   }
  75.   FPuts (StdOut, " file, decompressing.\n");
  76.   
  77.   
  78.   /* Allocate the buffers */
  79.   id_TrackBuf = (UBYTE *)myAllocMem (ID_TBSIZE, MEMF_CLEAR);
  80.   id_FileBuf  = (UBYTE *)myAllocMem (ID_FBSIZE, MEMF_CLEAR);
  81.   if (!id_TrackBuf || !id_FileBuf)
  82.   {
  83.     /* No Memory */
  84.     FPrintf (StdErr, "%s: Out of memory.\n", ProgName);
  85.     cleanExit(RETURN_FAIL, ERROR_NO_FREE_STORE);
  86.   }
  87.  
  88.   if (adfPkt->verify)
  89.   {
  90.     id_VTrackBuf = (UBYTE *) myAllocMem (ID_TBSIZE, MEMF_CLEAR);
  91.     if (!id_VTrackBuf)
  92.     {
  93.       /* Out of memory! */
  94.       FPrintf (StdErr, "%s: Out of memory.\n", ProgName);
  95.       cleanExit (RETURN_FAIL, ERROR_NO_FREE_STORE);
  96.     }
  97.   }
  98.   
  99.   /* Consume file header */
  100.   if (skipHead (adfPkt->ADFile, origName, fileType) == FALSE)
  101.   {
  102.     DOSError = IoErr();
  103.     
  104.     FPrintf (StdErr, "%s: Couldn't read file header.\n",ProgName);
  105.     
  106.     if (DOSError)
  107.       reportDOSError (DOSError);
  108.     
  109.     cleanExit (RETURN_FAIL, NULL);
  110.   }
  111.   
  112.   
  113.   /* Initialise the z_stream */
  114.   if (fileType == FT_ZLIB) winbits = 15;
  115.   else winbits = -15; /* windowBits is passed < 0 to suppress zlib header */    
  116.   infl_stream.zalloc = Z_NULL;
  117.   infl_stream.zfree  = Z_NULL;
  118.   infl_stream.opaque = Z_NULL;
  119.   zerr = inflateInit2 (&infl_stream, winbits);
  120.   if (zerr != Z_OK)
  121.   {
  122.     FPrintf (StdErr, "%s: Inflate Init Error - ", ProgName);
  123.     reportZLibError (zerr);
  124.     if (infl_stream.msg) FPrintf (StdErr, "\t(%s)\n", infl_stream.msg);
  125.     cleanExit (RETURN_FAIL, NULL);
  126.   }
  127.   
  128.   /* Start inflating */
  129.   infl_stream.avail_in  = 0;            /* Input buffer is empty    */
  130.   infl_stream.next_out  = id_TrackBuf;  /* Pointer to output buffer */
  131.   infl_stream.avail_out = ID_TBSIZE;    /* output buffer is empty   */
  132.   CRC = crc32 (NULL, Z_NULL, 0);        /* Initialise the CRC       */
  133.   nextTrack = adfPkt->startTrack;
  134.   while (1)
  135.   {
  136.     if (infl_stream.avail_in == 0)  /* Input is empty */
  137.     {
  138.       /* Fill the input buffer from file */
  139.       infl_stream.next_in  = id_FileBuf;
  140.       infl_stream.avail_in = Read (adfPkt->ADFile, id_FileBuf, ID_FBSIZE);
  141.       if (infl_stream.avail_in == 0)
  142.       {
  143.         FPrintf (StdErr, "%s: Error - Unexpected End-Of-File.\n", ProgName);
  144.         cleanExit (RETURN_ERROR, NULL);
  145.       }
  146.     }
  147.     
  148.     /* Fill the output buffer with inflated data */
  149.     while (1)
  150.     {
  151.       /* Check for Control-C break */
  152.       if (CTRL_C)
  153.       {
  154.         FPutC (StdOut, '\n');
  155.         FPrintf (StdErr, "%s - %s\n", breakText, ProgName);
  156.         inflateEnd (&infl_stream);
  157.         cleanExit (RETURN_WARN, NULL);
  158.       }
  159.       
  160.       /* Upate progress report */
  161.       FPuts (StdOut, "\rInflating ");
  162.       Flush (StdOut);
  163.       
  164.       zerr = inflate (&infl_stream, Z_NO_FLUSH);
  165.       if (zerr < Z_OK)
  166.       {
  167.         FPutC (StdOut, '\n');
  168.         FPrintf (StdErr, "%s: Inflate error - ", ProgName);
  169.         reportZLibError (zerr);
  170.         if (infl_stream.msg) FPrintf (StdErr, "\t%s\n", infl_stream.msg);
  171.         inflateEnd (&infl_stream);
  172.         cleanExit (RETURN_FAIL, NULL);
  173.       }
  174.       
  175.       /* Only flush the output buffer when it is completely full */
  176.       if (infl_stream.avail_out == 0)
  177.       {
  178.         if (nextTrack <= adfPkt->endTrack)
  179.         {
  180.           /* Update the CRC */
  181.           CRC = crc32 (CRC, id_TrackBuf, ID_TBSIZE);
  182.           
  183.           /* Update progress report */
  184.           FPuts (StdOut, "\rWriting   ");
  185.           FPUTS_TS (nextTrack, StdOut);
  186.           Flush (StdOut);
  187.           
  188.           /* Write to the disk */
  189.           TDError = writeTrack (id_TrackBuf, ID_TBTRACKS, nextTrack,
  190.                                 adfPkt->diskReq);
  191.           if (TDError)
  192.           {
  193.             FPutC (StdOut, '\n');
  194.             FPrintf (StdErr, "%s: Error writing to DF%ld: - ",
  195.                              ProgName,adfPkt->diskUnit);
  196.             reportTDError (TDError);
  197.             inflateEnd (&infl_stream);
  198.             cleanExit (RETURN_FAIL, NULL);
  199.           }
  200.           
  201.           if (adfPkt->verify)
  202.           {
  203.             /* Verify that the data was written correctly */
  204.             FPuts (StdOut, "\rVerifying ");
  205.             FPUTS_TS (nextTrack, StdOut);
  206.             Flush (StdOut);
  207.             
  208.             flushTrack (adfPkt->diskReq);
  209.             TDError = readTrack (id_VTrackBuf, ID_TBTRACKS, nextTrack, 
  210.                                  adfPkt->diskReq);
  211.             if (TDError)
  212.             {
  213.               FPutC (StdOut, '\n');
  214.               FPrintf (StdErr, "%s: Error reading from DF%ld - ", ProgName,
  215.                                                             adfPkt->diskUnit);
  216.               reportTDError (TDError);
  217.               inflateEnd (&infl_stream);
  218.               cleanExit (RETURN_ERROR, NULL);
  219.             }
  220.       
  221.             /* Check that the two buffers are identical */
  222.             if (memcmp (id_TrackBuf, id_VTrackBuf, ID_TBSIZE) != 0)
  223.             {
  224.               /* Verification error */
  225.               FPutC (StdOut, '\n');
  226.               FPrintf (StdErr, "%s: Verification Error on DF%ld:\n", ProgName,
  227.                                                             adfPkt->diskUnit);
  228.               inflateEnd (&infl_stream);
  229.               cleanExit (RETURN_ERROR, NULL);
  230.             }
  231.           }
  232.           
  233.           infl_stream.next_out  = id_TrackBuf;
  234.           infl_stream.avail_out = ID_TBSIZE;
  235.           nextTrack++;
  236.         }
  237.         else
  238.           /* We've reached the end */
  239.           zerr = Z_STREAM_END;
  240.       }
  241.       else
  242.         /* The buffer is not full, move along */
  243.         break;
  244.       
  245.       if (zerr == Z_STREAM_END)
  246.         /* Reached endTrack, or we reached the end of the */
  247.         /* compressed data stream.                        */
  248.         break;
  249.     }
  250.     if (zerr == Z_STREAM_END) break;
  251.   }
  252.   USize = infl_stream.total_out;
  253.   
  254.   FPrintf (StdOut, "\rInflated: %ld ==> %ld         ", infl_stream.total_in,
  255.                                                        USize);
  256.   Flush (StdOut);
  257.   
  258.   /* End the deflate process */
  259.   zerr = inflateEnd (&infl_stream);
  260.   if (zerr != Z_OK)
  261.   {
  262.     FPutC (StdOut, '\n');
  263.     FPrintf (StdErr, "%s: Inflate End Error - ", ProgName);
  264.     reportZLibError (zerr);
  265.     if (infl_stream.msg) FPrintf (StdErr, "\t(%s)\n", infl_stream.msg);
  266.     cleanExit (RETURN_FAIL, NULL);
  267.   }
  268.   
  269.   /* Check the CRC and USize */
  270.   if ( readTail (adfPkt->ADFile, &origCRC, &origUSize, fileType) == FALSE)
  271.   {
  272.     FPutC (StdOut, '\n');
  273.     FPrintf (StdErr, "%s: Couldn't read CRC or Size from file.\n", 
  274.                      ProgName);
  275.     cleanExit (RETURN_FAIL, NULL);
  276.   }
  277.   
  278.   if (fileType != FT_ZLIB)
  279.   {
  280.     if (CRC != origCRC)
  281.     {
  282.       FPutC (StdOut, '\n');
  283.       FPuts (StdErr, "Error: CRC Mismatch!\n");
  284.       cleanExit (RETURN_ERROR, NULL);
  285.     }
  286.     
  287.     if (USize != origUSize)
  288.     {
  289.       FPutC (StdOut, '\n');
  290.       FPuts (StdErr, "Error: Size mismatch!\n");
  291.       cleanExit (RETURN_ERROR, NULL);
  292.     }
  293.   }
  294.   
  295.   /* Free and clear buffers */
  296.   myFreeMem (id_TrackBuf);
  297.   myFreeMem (id_FileBuf);
  298.   if (id_VTrackBuf)
  299.     myFreeMem (id_VTrackBuf);
  300. }
  301.